<?php

namespace Handler;

use Extension\Tools;
use GatewayWorker\Lib\Db;
use Model\Room\RoomMain;
use Model\User;
use Workerman\Lib\Timer;
use Model\RoomBase;

class ZoneHandler {
	/**
	 * 单例
	 *
	 * @var ZoneHandler
	 */
	private static $m_Instance;
	/**
	 * 大区（初级场，中级场，高级场）
	 *
	 * @var array
	 */
	private $m_Zones;
	/**
	 *
	 * @var RoomMain[]
	 */
	private $m_Rooms;
	/**
	 * 距离定时更新所剩余的秒数
	 *
	 * @var int
	 */
	private $m_DayLag;
	/**
	 * 币值
	 *
	 * @var double
	 */
	private $m_CoinValue;
	/**
	 * 构造函数
	 */
	protected function __construct() {
		Timer::add ( 1, array (
				$this,
				'mb_TimerTask' 
		), array (), true );
		
		$this->m_DayLag = Tools::mb_GetTimeDifference ( date ( 'Y-m-d', strtotime ( "+1 day" ) ), Tools::mb_GetCurDateTime () );
	}
	/**
	 * 析构函数
	 */
	protected function __destruct() {
	}
	/**
	 * 获取单例
	 *
	 * @return \Handler\ZoneHandler
	 */
	public static function mb_GetInstance() {
		if (! (self::$m_Instance instanceof self)) {
			self::$m_Instance = new self ();
		}
		return self::$m_Instance;
	}
	/**
	 * 时间任务(每一秒执行一次)
	 */
	public function mb_TimerTask() {
		// 每日凌晨0时更新
		if (-- $this->m_DayLag == 0) {
			$this->m_DayLag = 86400;
			foreach ( $this->m_Rooms as $room ) {
				if (isset ( $room ))
					$room->mb_ResetRound();
			}
		}
		if ($this->m_Rooms != null) {
			foreach ( $this->m_Rooms as $room ) {
				if (isset ( $room ))
					$room->mb_Update ();
			}
		}
	}
	/**
	 * 初始化
	 */
	public function mb_Init() {
		$this->m_Rooms = array ();
		$this->mb_InitZones ();
		
		for($i = 0; $i < count ( $this->m_Rooms ); $i ++) {
			$this->m_Rooms [$i]->mb_Start ();
		}
	}
	/**
	 *
	 * @param User $user        	
	 * @param int $zoneId        	
	 * @return boolean
	 */
	public function mb_EnterRoom($user, $zoneId) {
		$zone = $this->m_Zones [$zoneId - 1];
		if (isset ( $zone )) {
			for($i = 0; $i < count ( $zone ['rooms'] ); $i ++) {
				$roomId = $zone ['rooms'] [$i];
				$room = $this->m_Rooms [$roomId];
				if ($room->mb_UserIn ( $user )) {
					$user->mb_EnterRoom ( $roomId );
					return true;
				}
			}
			return false;
		} else {
			return false;
		}
	}
	/**
	 *
	 * @param User $user        	
	 * @param int $roomId        	
	 * @return boolean
	 */
	public function mb_ReEnterRoom($user, $roomId) {
		$room = $this->m_Rooms [$roomId];
		
		if (isset ( $room ) && $room->mb_UserIn ( $user )) {
			$user->mb_EnterRoom ( $roomId );
			return true;
		}
		return false;
	}
	/**
	 *
	 * @param string $roomName        	
	 * @param User $user        	
	 * @return boolean
	 */
	public function mb_ExitRoom($roomId, $user) {
		if (isset ( $this->m_Rooms [$roomId] )) {
			if ($this->m_Rooms [$roomId]->mb_UserOut ( $user )) {
				$user->mb_ExitRoom ();
				return true;
			} else {
				return false;
			}
		}
		return true;
	}
	/**
	 * 转发房间数据
	 *
	 * @param int $roomId        	
	 * @param unknown $json        	
	 * @param user $user        	
	 */
	public function mb_RoomData($roomId, $json, $user) {
		if (isset ( $this->m_Rooms [$roomId] ))
			$this->m_Rooms [$roomId]->mb_DataIn ( $user, $json );
	}
	/**
	 * 初始化大区
	 */
	private function mb_InitZones() {
		$this->m_Rooms = array ();
		$this->m_Zones = Db::instance ( 'game' )->select ( '*' )->from ( 'zoneinfo' )->query ();
		$this->m_CoinValue = $this->m_Zones [0] ['coinvalue'];
		for($i = 0; $i < count ( $this->m_Zones ); $i ++) {
			$count = $this->m_Zones [$i] ['count'];
			$this->m_Zones [$i] ['rooms'] = $this->mb_InitRooms ( $this->m_Zones [$i], $count );
		}
	}
	/**
	 *
	 * @param array $zone        	
	 * @param int $count        	
	 * @return number[]
	 */
	private function mb_InitRooms($zone, $count) {
		$roomIds = array ();
		for($i = 0; $i < $count; $i ++) {
			$roomId = count ( $this->m_Rooms );
			$num = $i + 1;
			$this->m_Rooms [] = new RoomMain ( $roomId, $zone ['id'], $num, $zone ['name'] . " - $num 号房", RoomBase::TYPE_FREE, $zone ['difen'], $zone ['minenter'], $zone ['maxenter'], $zone ['choushui'], $zone ['difficulty'] );
			$roomIds [] = $roomId;
		}
		return $roomIds;
	}
	/**
	 *
	 * @param unknown $zoneId        	
	 * @param unknown $count        	
	 */
	public function mb_AddZoneRooms($zoneId, $count) {
		$zone = $this->m_Zones [$zoneId - 1];
		for($i = count ( $zone ['rooms'] ); $i < $count; $i ++) {
			$roomId = count ( $this->m_Rooms );
			$num = $i + 1;
			$room = new RoomMain ( $roomId, $zone ['id'], $num, $zone ['name'] . " - $num 号房", RoomBase::TYPE_FREE, $zone ['difen'], $zone ['minenter'], $zone ['maxenter'], $zone ['choushui'], $zone ['difficulty'] );
			$this->m_Rooms [] = $room;
			$this->m_Zones [$zoneId - 1] ['rooms'] [] = $roomId;
			$room->mb_Start ();
		}
		Db::instance ( 'game' )->update ( 'zoneinfo' )->cols ( array (
				"count" => $count 
		) )->where ( "id='$zoneId'" )->query ();
	}
	
	/**
	 *
	 * @param unknown $zoneId        	
	 * @param unknown $count        	
	 * @return boolean
	 */
	public function mb_RemoveZoneRooms($zoneId, $count) {
		// $zone = $this->m_Zones [$zoneId - 1];
		for($i = $count; $i < count ( $this->m_Zones [$zoneId - 1] ['rooms'] ); $i ++) {
			$roomId = $this->m_Zones [$zoneId - 1] ['rooms'] [$i];
			$players = $this->m_Rooms [$roomId]->m_Algo->mb_GetRealPlayerCount ();
			if ($players > 0)
				return false;
		}
		for($i = $count; $i < count ( $this->m_Zones [$zoneId - 1] ['rooms'] ); $i ++) {
			$roomId = $this->m_Zones [$zoneId - 1] ['rooms'] [$i];
			$this->m_Rooms [$roomId] = null;
		}
		array_splice ( $this->m_Zones [$zoneId - 1] ['rooms'], $count );
		
		Db::instance ( 'game' )->update ( 'zoneinfo' )->cols ( array (
				"count" => $count 
		) )->where ( "id='$zoneId'" )->query ();
		
		return true;
	}
	public function mb_UpdateZoneMinEnter($zoneId, $minEnter) {
		$this->m_Zones [$zoneId - 1] ['minenter'] = ( int ) $minEnter;
		
		for($i = 0; $i < count ( $this->m_Zones [$zoneId - 1] ['rooms'] ); $i ++) {
			$roomId = $this->m_Zones [$zoneId - 1] ['rooms'] [$i];
			$this->m_Rooms [$roomId]->mb_UpdateRoomSetting ( array (
					'minenter' => $minEnter 
			) );
		}
		
		Db::instance ( 'game' )->update ( 'zoneinfo' )->cols ( array (
				'minenter' => $minEnter 
		) )->where ( "id='$zoneId'" )->query ();
	}
	/**
	 *
	 * @return array
	 */
	public function mb_GetZones() {
		return $this->m_Zones;
	}
	public function mb_GetZoneForId($zoneId) {
		return $this->m_Zones [$zoneId - 1];
	}
	/**
	 * 获取大区房间
	 *
	 * @param unknown $zoneId        	
	 * @return \Model\unknown[][]|\Model\Room\unknown[][]|number[][]
	 */
	public function mb_GetRooms($zoneId) {
		$zone = $this->m_Zones [$zoneId - 1];
		$roomIds = $zone ['rooms'];
		$roomInfos = array ();
		for($i = 0; $i < count ( $roomIds ); $i ++) {
			$roomInfos [] = $this->m_Rooms [$roomIds [$i]]->mb_GetRoomInfo ();
		}
		return $roomInfos;
	}
	public function mb_GetRoom($roomId) {
		if (isset ( $this->m_Rooms [$roomId] ))
			return $this->m_Rooms [$roomId];
		else
			return null;
	}
	/**
	 * 创建房间
	 *
	 * @param int $zoneId        	
	 * @param int $roomId        	
	 * @return boolean
	 */
	public function mb_CreateRoom($zoneId, $roomId) {
		if (isset ( $this->m_Rooms [$roomId] ))
			return false;
		
		$zone = $this->m_Zones [$zoneId - 1];
		$this->m_Rooms [$roomId] = new RoomMain ( $roomId, $zoneId, $roomId, "$roomId 号房", RoomBase::TYPE_BUDDY, $zone ['difen'], $zone ['minenter'], $zone ['maxenter'], $zone ['choushui'], $zone ['difficulty'] );
		$this->m_Rooms [$roomId]->mb_Start ();
		return true;
	}
	/**
	 * 销毁房间
	 *
	 * @param int $roomId        	
	 */
	public function mb_DestoryRoom($roomId) {
		if (isset ( $this->m_Rooms [$roomId] )) {
			unset ( $this->m_Rooms [$roomId] );
		}
	}
	/**
	 * 机器人进入房间
	 *
	 * @param int $roomId        	
	 * @return boolean
	 */
	public function mb_RobotEnterRoom($roomId) {
		$robot = UserHandler::mb_GetInstance ()->mb_GetIdleRobot ();
		if (isset ( $robot ) == false)
			return false;
		
		if ($robot->m_Coin <= 100 * $this->m_CoinValue)
			$robot->mb_Save ( mt_rand ( 100, 3000 ) * $this->m_CoinValue );
		
		$room = $this->m_Rooms [$roomId];
		if ($room->mb_UserIn ( $robot )) {
			$robot->mb_EnterRoom ( $roomId );
			return true;
		} else {
			return false;
		}
	}
	/**
	 * 机器人退出房间
	 *
	 * @param int $roomId        	
	 * @param User $robot        	
	 * @return boolean
	 */
	public function mb_RobotExitRoom($roomId, $robot) {
		if ($this->m_Rooms [$roomId]->mb_UserOut ( $robot )) {
			$robot->mb_ExitRoom ();
			return true;
		} else {
			return false;
		}
	}
	// ------------------------------------记录日志----------------------------------//
	/**
	 * 从数据库中获取房间信息
	 *
	 * @param unknown $zoneId        	
	 * @param unknown $roomInfo        	
	 * @return array
	 */
	public function mb_GetRoomInfo($zoneId, $roomNum) {
		return Db::instance ( 'game' )->select ( '*' )->from ( 'roominfo' )->where ( "zoneid='$zoneId' AND roomnum='$roomNum'" )->row ();
	}
	/**
	 * 创建或更新房间信息
	 *
	 * @param unknown $zoneId        	
	 * @param unknown $roomNum        	
	 * @param unknown $round        	
	 * @param unknown $level        	
	 * @param unknown $chouShui        	
	 * @param unknown $totalChouShui        	
	 * @param unknown $totalWin        	
	 * @param unknown $controlId        	
	 * @param unknown $controlLevel        	
	 */
	public function mb_CreateOrUpdateRoomInfo($zoneId, $roomNum, $round, $difficulty, $chouShui, $totalUserChouShui, $totalRobotChouShui, $totalWin, $controlId, $controlDifficulty, $robotCount) {
		if (Db::instance ( 'game' )->select ( 'id' )->from ( 'roominfo' )->where ( "zoneid='$zoneId' AND roomnum='$roomNum'" )->row ()) {
			// 房间记录已存在
			Db::instance ( 'game' )->update ( 'roominfo' )->where ( "zoneid='$zoneId' AND roomnum='$roomNum'" )->cols ( array (
					'round' => $round,
					'difficulty' => $difficulty,
					'choushui' => $chouShui,
					'totaluserchoushui' => $totalUserChouShui,
					'totalrobotchoushui' => $totalRobotChouShui,
					'totalwin' => $totalWin,
					'controlid' => $controlId,
					'controldifficulty' => $controlDifficulty,
					'robotcount' => $robotCount 
			) )->query ();
		} else {
			// 房间记录不存在
			Db::instance ( 'game' )->insert ( 'roominfo' )->cols ( array (
					'zoneid' => $zoneId,
					'roomnum' => $roomNum,
					'round' => $round,
					'difficulty' => $difficulty,
					'choushui' => $chouShui,
					'totaluserchoushui' => $totalUserChouShui,
					'totalrobotchoushui' => $totalRobotChouShui,
					'totalwin' => $totalWin,
					'controlid' => $controlId,
					'controldifficulty' => $controlDifficulty,
					'robotcount' => $robotCount 
			) )->query ();
		}
	}
	/**
	 * 插入游戏记录
	 *
	 * @param unknown $zoneId        	
	 * @param unknown $roomNum        	
	 * @param unknown $name        	
	 * @param unknown $round        	
	 * @param unknown $isBanker        	
	 * @param unknown $bankerMul        	
	 * @param unknown $playerMul        	
	 * @param unknown $cardType        	
	 * @param unknown $win        	
	 * @param unknown $chouShui        	
	 * @param unknown $coins        	
	 */
	public function mb_InsertGameRecord($zoneId, $roomNum, $id, $name, $round, $isBanker, $bankerMul, $playerMul, $cardType, $win, $chouShui, $coins, $isControl, $controlDiff, $isRobot, $diFen) {
		Db::instance ( 'game' )->insert ( 'recordlog' )->cols ( array (
				'zoneid' => $zoneId,
				'roomnum' => $roomNum,
				'userid' => $id,
				'name' => $name,
				'round' => $round,
				'isbanker' => $isBanker,
				'bankermul' => $bankerMul,
				'playermul' => $playerMul,
				'cardtype' => $cardType,
				'win' => $win,
				'choushui' => $chouShui,
				'coins' => $coins,
				'iscontrol' => $isControl,
				'controldifficulty' => $controlDiff,
				'isrobot' => $isRobot,
				'difen' => $diFen 
		) )->query ();
	}
	public function mb_QueryGameRecord($where) {
		return Db::instance ( 'game' )->select ( '*' )->from ( 'recordlog' )->where ( $where )->orderByDESC ( array (
				'id' 
		) )->query ();
	}
	public function mb_DeleteData() {
		Db::instance ( 'game' )->delete ( 'recordlog' )->query ();
		Db::instance ( 'game' )->delete ( 'roominfo' )->query ();
	}
	public function mb_TotalAccount() {
		$userChouShui = Db::instance ( 'game' )->select ( 'sum(totaluserchoushui) as choushui' )->from ( 'roominfo' )->row () ['choushui'];
		$robotChouShui = Db::instance ( 'game' )->select ( 'sum(totalrobotchoushui) as choushui' )->from ( 'roominfo' )->row () ['choushui'];
		$userWin = Db::instance ( 'game' )->select ( 'sum(totalwin) as win' )->from ( 'roominfo' )->row () ['win'];
		return array (
				'userchoushui' => ( double ) $userChouShui,
				'robotchoushui' => ( double ) $robotChouShui,
				'userwin' => ( double ) $userWin 
		);
	}
	/**
	 * 保存币值
	 *
	 * @param unknown $coinValue        	
	 */
	public function mb_SaveCoinValue($coinValue) {
		$this->m_CoinValue = $coinValue;
		Db::instance ( 'game' )->update ( 'zoneinfo' )->cols ( array (
				'coinvalue' => $coinValue 
		) )->query ();
	}
	
	/**
	 * 获取私有成员
	 *
	 * @param unknown $property_name        	
	 * @return unknown|NULL
	 */
	public function __get($property_name) {
		if (isset ( $this->$property_name )) {
			return ($this->$property_name);
		} else {
			return (NULL);
		}
	}
}